package com.stone.serverless.web;

import cn.hutool.extra.spring.EnableSpringUtil;
import com.stone.serverless.web.interceptor.AuthInterceptor;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description: TODO
 * @Author: MECHREVO
 * @Date: 2022/1/18 8:53
 * @Version: 1.0.0
 */

@EnableWebMvc
@EnableSpringUtil
@Configuration
public class MvcConfiguration implements WebMvcConfigurer, ApplicationContextAware {

    private ServerlessRequestResponseBodyMethodProcessor serverlessRequestResponseBodyMethodProcessor;

    private ClassLoaderResourceResolver classLoaderResourceResolver;

    private AuthInterceptor authInterceptor;


    public AuthInterceptor getAuthInterceptor() {
        return authInterceptor;
    }

    public ClassLoaderResourceResolver getClassLoaderResourceResolver() {
        return classLoaderResourceResolver;
    }

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        //    mappingJackson2HttpMessageConverter.su
        converters.add(mappingJackson2HttpMessageConverter);
        serverlessRequestResponseBodyMethodProcessor = new ServerlessRequestResponseBodyMethodProcessor(converters);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
         classLoaderResourceResolver = new ClassLoaderResourceResolver();
        registry.addResourceHandler("**/js/**").resourceChain(true)
                .addResolver(classLoaderResourceResolver);
        registry.addResourceHandler("**/css/**").resourceChain(true)
                .addResolver(classLoaderResourceResolver);
        registry.addResourceHandler("**/font/**").resourceChain(true)
                .addResolver(classLoaderResourceResolver);

        registry.addResourceHandler("**/templates/**.html").addResourceLocations("classpath:/templates/").resourceChain(true)
                .addResolver(classLoaderResourceResolver);
    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {

        //   configurer.setUrlPathHelper()
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        ClassLoaderResourceViewResolver classLoaderResourceViewResolver = new ClassLoaderResourceViewResolver();
        //classLoaderResourceViewResolver.setSuffix(".html");
        classLoaderResourceViewResolver.setViewClass(ClassLoaderResourceView.class);
        registry.viewResolver(classLoaderResourceViewResolver);
    }

    /**
     * 跨域
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                //.allowedOrigins("*")
                .allowedHeaders("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "PUT", "DELETE","OPTIONS")
                .maxAge(3600);
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
         authInterceptor = new AuthInterceptor();
        registry.addInterceptor(authInterceptor);
        registry.addInterceptor(new ClassLoaderResourceHandlerInterceptor());
    }


    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new RpcServiceHandlerMethodArgumentResolver());

    }

    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
        handlers.add(new RpcServiceHandlerMethodReturnValueHandler());
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        RequestMappingHandlerAdapter requestMappingHandlerAdapter = applicationContext.getBean(RequestMappingHandlerAdapter.class);
        List<HandlerMethodReturnValueHandler> returnValueHandlers = new ArrayList<>();

        returnValueHandlers.add(serverlessRequestResponseBodyMethodProcessor);
        returnValueHandlers.addAll(requestMappingHandlerAdapter.getReturnValueHandlers());
        requestMappingHandlerAdapter.setReturnValueHandlers(returnValueHandlers);
    }
}
